/**
 * 折线图
 */
var lineMapChart = {
  /**
   * 初始化
   */
  init: function () {
    this.state = {
      allData: [],
      ficNames: [], // 所有的物种名字
      ficName: '', // 当前 折线图 渲染的物种名字
      ficNameMap: '', // 当前 地图 渲染的物种名字
      years: [], // X轴
      renderData: [], // 折线图数据
      mapData: [], // 地图撒点的数据
    }
    this.getData();
  },
  /**
   * 获取数据
   */
  getData: function () {
    var self = this;
    d3.csv('./data/ACT_Wildlife_Atlas_Records.csv', function (error, data) {
      if (error) {
        console.error(error);
      }
      self.state.allData = data;
      self.render();
      self.renderMap();
    })
  },
  /**
   * 以下是关于折线图部分的逻辑
   */
  render: function () {
    this.renderNames();
    this.filterData();
  },
  // 渲染 名字列表
  renderNames: function () {
    var data = this.state.allData;
    var ficNames = [];
    var dom = "";
    data.forEach(function (d) {
      if (ficNames.indexOf(d.ScientificName.trim()) === -1) {
        ficNames.push(d.ScientificName.trim())
      }
    })
    this.state.ficNames = ficNames;
    this.state.ficName = ficNames[0];
    this.state.ficNameMap = ficNames[0];
    ficNames.forEach(function (d) {
      dom += "<option>" + d.trim() + "</option>"
    })
    $('.ficName-list').html(dom)
    $('.map-sf-list').html(dom)
  },
  /**
   * 绑定图表事件
   */
  bindEvent: function () {
    var xScale = this.state.xScale;
    var years = this.state.years;
    var renderData = this.state.renderData;
    var self = this;
    $('.ficName-sf-list').on('change', function () {
      var ficName = $('.ficName-list').val();
      self.state.ficName = ficName;
      self.filterData();
    })

    d3.select('.line-chart').on('mousemove', function () {
        var x = document.querySelector('.line-chart').getBoundingClientRect().x;
        var event = d3.event;
        var top = d3.event.pageY;
        var left = d3.event.pageX;

        var partX = left - x; // 移动进图表的水平距离
        var xIndex = parseInt(xScale.invert(partX));

        var option = {
          el: '.auto-tooltip',
          location: {
            x: left,
            y: top
          },
          data: [{
            name: '年份',
            value: years[xIndex]
          }, {
            name: '数量',
            value: renderData[xIndex] ? renderData[xIndex].count : 0
          }]
        }
        var el = self.tooltip(option)
        el.show()
      })
      .on('mouseout', function () {
        $('.auto-tooltip').hide()
      })
  },
  tooltip: function (option) {
    var el = option.el
    var location = option.location
    var data = option.data
    var text = ''
    for (var i = 0, length = data.length; i < length; i++) {
      if (length == 1) {
        text += data[i].name + '<br>' + data[i].value
      } else {
        text += data[i].name + '：' + data[i].value + '<br>'
      }
    }
    $(el).html(text)
    var globalWidth = $('body').outerWidth()
    var globalHeight = $('body').outerHeight()
    var elWidth = $(el).outerWidth()
    var elHeight = $(el).outerHeight()
    location.x = location.x - elWidth / 2
    location.y = location.y - elHeight - 10
    if (location.x + elWidth / 2 > globalWidth) {
      location.x = globalWidth - elWidth
    }
    $(el).css({
      left: location.x,
      top: location.y
    })
    return $(el)
  },
  /**
   * 过滤数据
   */
  filterData: function () {
    // 过滤 产量数据
    var allData = this.state.allData;
    var ficName = this.state.ficName;

    var renderData = [];
    var years = []
    var fileData = allData.filter(function (d) {
      return d.ScientificName.trim() === ficName;
    })

    // 得到 X轴
    fileData.forEach(function (d) {
      if (years.indexOf(parseInt(d.RecordDate.split('/')[2], 10)) === -1) {
        years.push(parseInt(d.RecordDate.split('/')[2], 10));
      }
    })
    // 累加统计 count 值
    years.forEach(function (d) {
      var count = 0
      fileData.forEach(function (s) {
        if (parseInt(s.RecordDate.split('/')[2], 10) === d) {
          count += parseFloat(s.individualCount, 10)
        }
      })
      renderData.push({
        name: ficName,
        count: count,
        year: d
      })
    })

    this.state.renderData = renderData.sort(function (a, b) {
      return a.year - b.year
    })
    this.state.years = years;
    // 将两组数据用于绘图
    this.renderChart();
  },
  /**
   * 绘制折线图
   */
  renderChart: function () {
    var renderData = this.state.renderData
    var years = this.state.years;

    // console.log(renderData, years);

    $('.line-chart').html('');
    var colors = ['#1867d8', '#4cc6ec']; // 两个填充色
    var width = $('.line-chart').outerWidth();
    var height = 500;
    var svg = d3.select('.line-chart')
    var padding = {
      top: 20,
      right: 100,
      bottom: 100,
      left: 100
    };

    var max = d3.max(renderData, function (d) {
      return d.count
    })

    var xScale = d3.scaleLinear()
      .domain([0, years.length])
      .range([0, width - padding.left - padding.right]);

    this.state.xScale = xScale;

    var yScale = d3.scaleLinear()
      .domain([0, max * 1.1])
      .range([height - padding.top - padding.bottom, 0]);

    // 创建产量的直线生成器
    var linePath = d3.line()
      .curve(d3.curveCardinal.tension(0.5))
      .x(function (d, i) {
        return xScale(i);
      })
      .y(function (d) {
        return yScale(d.count);
      });

    // 添加路径
    svg.append("path")
      .data([renderData])
      .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
      .attr("d", function (d) {
        return linePath(d);
      })
      .attr("fill", "none")
      .attr("stroke-width", 3)
      .attr("stroke", colors[0]);
    // x轴
    var xAxis = d3.axisBottom()
      .scale(xScale)
      .ticks(years.length)
      .tickFormat(function (d, i) {
        return years[i]
      })
    // y轴
    var yAxis = d3.axisLeft()
      .scale(yScale)

    svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")")
      .call(xAxis);

    svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
      .call(yAxis);

    this.bindEvent(); // 图表绘制完成，绑定事件
  },
  /**
   * 以下是关于地图部分的逻辑
   */
  renderMap: function () {
    this.renderMapYears();
    this.filterMapData();
  },
  /**
   * ScientificName 下拉列表 和折线图的一样
   * 直接绘制 年份 下拉列表
   */
  renderMapYears: function () {
    var data = this.state.allData;
    var mapYears = [];
    var dom = "";
    data.forEach(function (d) {
      if (mapYears.indexOf(parseInt(d.RecordDate.split('/')[2], 10)) === -1) {
        mapYears.push(parseInt(d.RecordDate.split('/')[2], 10))
      }
    })
    this.state.mapYears = mapYears;
    this.state.mapYear = mapYears[0];
    mapYears.forEach(function (d) {
      dom += "<option>" + d + "</option>"
    })
    $('.map-years-list').html(dom)
  },
  /**
   * 求 地图渲染的数据
   */
  filterMapData: function () {
    var ficNameMap = this.state.ficNameMap;
    var data = this.state.allData;
    // 根据物种名字和年份过滤数据
    var fileData = data.filter(function (d) {
      return d.ScientificName.trim() === ficNameMap
    })
    this.state.mapData = fileData;

    this.renderMapChart();
  },
  /**
   * 地图撒点
   */
  renderMapChart: function () {
    $('.map-chart').html('');
    var self = this;
    var mapData = this.state.mapData;
    // console.log(mapData)
    //求最大值和最小值
    var maxValue = d3.max(mapData, function (d) {
      return parseFloat(d.individualCount, 10);
    })
    var minValue = d3.min(mapData, function (d) {
      return parseFloat(d.individualCount, 10)
    })

    //定义一个线性比例尺，将最小值和最大值之间的值映射到[minR,maxR]
    var minR = 6;
    var maxR = 10;
    var linearR = d3.scaleLinear()
      .domain([minValue, maxValue])
      .range([minR, maxR]);

    var width = $('.map-chart').outerWidth();;
    var height = 500;
    var svg = d3.select('.map-chart');

    //请求json
    d3.json("script/canberra.geojson", function (error, root) {
      if (error) return console.error(error);
      // 绘制地图 path
      var features = root.features;
      //定义地图的投影
      var scale = self.getZoomScale(features)
      var center = self.getCenters(features)
      var projection = d3.geoMercator() // 球形墨卡托投影
        .scale(scale * 3600)
        .center(center)
        .translate([width / 2, height / 2])
      //定义地形路径生成器
      var path = d3.geoPath()
        .projection(projection); //设定投影

      var groups = svg.append("g").attr('transform', 'translate(0, -17500)')
      groups.selectAll("path")
        .data(features)
        .enter()
        .append("path")
        .attr("class", "province")
        .attr('stroke', '#1866cc')
        .attr('stroke-width', 2)
        .attr('fill', 'rgba(17, 27, 142, 0.9)')
        .attr("d", path) //使用路径生成器
      // 绘制地图撒点
      var dotes = groups.append('g').attr('class', 'dotes');
      var dote = dotes.selectAll('.dote')
        .data(mapData)
        .enter()
        .append('g')
        .attr('class', 'dote')

      dote.append('circle')
        .attr("transform", function (d) {
          //计算标注点的位置
          // debugger
          var coor = projection([d.Easting_MGA, d.Northing_MGA]);
          return "translate(" + coor[0] + "," + coor[1] + ")";
        })
        .attr('r', function (d) {
          return linearR(parseFloat(d.individualCount, 10))
        })
        .attr('stroke-width', 3)
        .attr('stroke', '#54d6ff')
        .attr('fill', 'rgb(23, 69, 150)')
        .on('mousemove', function (d) {
          var event = d3.event;
          var top = d3.event.pageY;
          var left = d3.event.pageX;
          var option = {
            el: '.auto-tooltip',
            location: {
              x: left,
              y: top
            },
            data: [{
              name: '数量',
              value: parseFloat(d.individualCount, 10)
            }, {
              name: '年份',
              value: d.RecordDate.split('/')[2]
            },{
              name: '地理坐标',
              value: [d.Easting_MGA, d.Northing_MGA]
            }]
          }
          var el = self.tooltip(option)
          el.show()
        })
        .on('mouseout', function () {
          $('.auto-tooltip').hide()
        })


        // // 添加年份文本
        // var yearText = dotes.selectAll('.text')
        //   .data(mapData)
        //   .enter()
        //   .append('g')
        //   .attr('class', 'text')
        
        // yearText.append('text')
        //   .attr("transform", function (d) {
        //     //计算标注点的位置
        //     // debugger
        //     var coor = projection([d.Easting_MGA, d.Northing_MGA]);
        //     return "translate(" + coor[0] + "," + coor[1] + ")";
        //   })
        //   .attr('fill', 'red')
        //   .text(function(d) {
        //     return d.RecordDate.split('/')[2]
        //   })
    });

    this.bindMapEvent();
  },
  getZoomScale: function (features) {
    var width = 1170;
    var height = 500;
    var longitudeMin = 100000 // 最小经度
    var latitudeMin = 100000 // 最小维度
    var longitudeMax = 0 // 最大经度
    var latitudeMax = 0 // 最大纬度
    features.map((e) => {
      var a = d3.geoPath().bounds(e) // [[最小经度，最小维度][最大经度，最大纬度]]
      if (a[0][0] < longitudeMin) {
        longitudeMin = a[0][0]
      }
      if (a[0][1] < latitudeMin) {
        latitudeMin = a[0][1]
      }
      if (a[1][0] > longitudeMax) {
        longitudeMax = a[1][0]
      }
      if (a[1][1] > latitudeMax) {
        latitudeMax = a[1][1]
      }
    })
    var a = longitudeMax - longitudeMin
    var b = latitudeMax - latitudeMin
    return Math.min(width / a, height / b)
  },
  getCenters: function (features) {
    var longitudeMin = 100000
    var latitudeMin = 100000
    var longitudeMax = 0
    var latitudeMax = 0
    features.forEach((e) => {
      var a = d3.geoPath().bounds(e)
      if (a[0][0] < longitudeMin) {
        longitudeMin = a[0][0]
      }
      if (a[0][1] < latitudeMin) {
        latitudeMin = a[0][1]
      }
      if (a[1][0] > longitudeMax) {
        longitudeMax = a[1][0]
      }
      if (a[1][1] > latitudeMax) {
        latitudeMax = a[1][1]
      }
    })
    var a = (longitudeMax + longitudeMin) / 2
    var b = (latitudeMax + latitudeMin) / 2
    return [a, b]
  },
  /**
   * 绑定地图的事件
   */
  bindMapEvent() {
    var self = this;
    $('.ficName-list').on('change', function () {
      var ficNameMap = $('.ficName-list').val();
      self.state.ficNameMap = ficNameMap;
      self.filterMapData();
    })
  }
}

lineMapChart.init()